iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
0

Event Queue 觀念重點

Event Queue 就是事件佇列,一次只能執行一件事,好比是買口罩排隊的概念,誰先排就誰先拿,先進先出的概念。
等待條件觸發在 JavaScript 稱為 Event queue。像是 setTimeout, addEventListener, XMLHttpRequest 等等,這些方法在執行時會先將事件放到這地方,並將所有的事件堆疊完成後,才會開始讓 event queue 內的事件被觸發。

JavaScript是單線程語言

JavaScript 是 Single Thread,啟動JavaScript語法時只會啟動一顆CPU單核,一次只能做一件事。

Event Queue利用時間差

讓 JavaScript 感覺好像可以同時做很多事情,其實沒有,只是利用 event queue 產生時間差。

計時器,AJAX等等不是單線程

setTimeout , AJAX , Promise 等等是屬於 WebAPIs,不在 JavaScript 單線程限制範圍內。

Event Queue Demo

Demo 1 / 單線程

console.log("a");                  //1.先執行 a
function run(){                    // run 的函數
    console.log("b");
}
run();                             //2.執行 run 的函數得到 b
console.log("c");                  //3.最後執行 c

//---------------------------------打上以上語法,會依照單一線程陸續出現以下順序
a
b
c

Demo 2 / 非同步(單線程)

console.log("a");                  //1.先執行 a
function run(){                    // run 的函數
    console.log("b");
}
setTimeout(run,3000)               //2.使用計時器會放入Event Queue,過3秒後執行 run 的函數得到 b
console.log("c");                  //3.執行 c 完後,再去執行已經放進Event Queue的 b (一次只能執行一件事)

//---------------------------------打上以上語法,出現以下順序,
a
c
undefined                           //等待計時器
b                                   //過3秒後出現b

Demo 3 / 非同步(WebAPIs)

console.log("a");                  //1.先執行 a
function run(){                    // run 的函數
    console.log("b");
}
setTimeout(run,3000)               //2.將計時器放入第一個event queue,3秒後執行 run 的函數得到 b
var start = Date.now();             
while(Date.now() - start <= 5000){ //3.將迴圈放入第二個event queue,執行 5 秒鐘
}
console.log("c");                  //4.執行 c ,

//---------------------------------打上以上語法,出現以下順序,
a
c                                   //與b同時出現
undefined                           //等待計時器
b                                   //與c同時出現

c、b 會同時出現,是因為跑放入第一個queue的計時器b,3秒後執行run函數得到b,b在queue裡待著,
然後再執行第二個queue的迴圈,5秒鐘後,queue裡沒有其他要做的,就把b放出來,就會同步跟c出現。


AJAX 觀念重點

請求回應方式

  • 傳統網頁 :
    請求 > 等待回應 > 請求 > 等待回應 ... 一直重複一個請求,在等待一個回應後,才能再請求動作。
  • AJAX網頁 :
    在背景送出請求取得回應,同時還可以繼續在網頁上繼續動作

名稱由來

AJAX原名為 Asynchronous JavaScript and XML,其中XML,是早期比較流行的資料交換格式,
現在是流行JSON格式。

目前常見的底層 (原生語法..等)

  • XMLHttpRequest ( IE7以上支援、jQuery, Axios )
  • fetch ( 較新,HTML5才有、IE11(含)以下Bye了 )

測試用API

AJAX Demo

Demo 1 / 非同步GET請求發送

利用測試的API,得到連結套回程式碼中

利用瀏覽器 Console ,輸入程式碼

console.log("start");
var xhr = new XMLHttpRequest();
xhr.addEventListener('load',function(){
    console.log(this.responseText);
});
xhr.open('GET','測試API產生出來的網址',true); //true啟動非同步 
xhr.send();
console.log("end");
-----------------------------------輸入後會得到以下非同步結果
start
end
undefined
message;info

依序處理console,碰到要請求回應的就在背景處理,讓程式碼繼續往下跑,
所以會先出來 start 再來跳過請求處理,出來 end,最後等待讀取完畢出現 message;info

Demo 2 / 同步GET請求發送

console.log("start");
var xhr = new XMLHttpRequest();
xhr.open('GET','測試API產生出來的網址',false); //同步
xhr.send();
console.log(xhr.responseText);
console.log("end");
-----------------------------------輸入後會得到以下結果
start
message;info
end

同步會先 start,再來等待中間那段請求產生的文字message;infoend會最後才出現。

建議盡可能都使用非同步處理,因為使用同步可能會等待很多時間處理,可能會影響渲染網頁畫面不完全,而有不好使用體驗。

Demo 3 / 非同步POST請求發送

如果要傳送資料給遠端,將GET改成POST,如果要帶參數傳回去可用FormData()方式處理

console.log("start");
var data = new FormData();  //使用參數資料
data.append('id','5');      //寫入參數
var xhr = new XMLHttpRequest();
xhr.addEventListener('load',function(){
    console.log(this.responseText);
});
xhr.open('POST','測試API產生出來的網址',true); //非同步
xhr.send(data);   //帶入data參數資料
console.log("end");

Demo 4 / 同步POST請求發送

console.log("start");
var data = new FormData();  //使用參數資料
data.append('id','5');      //寫入參數
var xhr = new XMLHttpRequest();
xhr.open('GET','測試API產生出來的網址',false); //同步
xhr.send(data);   //帶入data參數資料
console.log(xhr.responseText);
console.log("end");

Demo 5 / fetch發送GET請求

fetch("測試API產生出來的網址").then(response => {
    return response.json();
}).then(data => {
    console.log(data)
})

Demo 6 / fetch發送POST請求

var data = new FormData();
data.append('id','5');
fetch("測試API產生出來的網址",{
    method:'POST',
    body: data
}).then(response => {
    return response.json();
}).then(data => {
    console.log(data)
})

上一篇
10. ES6 - 樣板字面值
下一篇
12. Promise
系列文
JS 作品實戰應用 - Vue 電商網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言